bitkeeper revision 1.105.1.4 (3e5e6300OW6aJoXNU_rtBiUn9RxCUQ)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Thu, 27 Feb 2003 19:12:00 +0000 (19:12 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Thu, 27 Feb 2003 19:12:00 +0000 (19:12 +0000)
network.c, dev.c:
  Fixed network transmit event dispatch. Was broken and not sending inter-CPU interrupts.

xen/net/dev.c
xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c

index 0bf8125014680ff3e784cc1e7139832e4e290afd..03039e9c818308e0f347b4295b06ab93de4a14d1 100644 (file)
@@ -657,10 +657,11 @@ static void add_to_net_schedule_list_tail(net_vif_t *vif)
 /* Destructor function for tx skbs. */
 static void tx_skb_release(struct sk_buff *skb)
 {
-    int i;
+    int i, send = 0;
     net_vif_t *vif = sys_vif_list[skb->src_vif];
     unsigned int idx;
     tx_shadow_entry_t *tx;
+    unsigned long cpu_mask;
     
     for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ )
         put_page_tot(skb_shinfo(skb)->frags[i].page);
@@ -691,9 +692,7 @@ static void tx_skb_release(struct sk_buff *skb)
         if ( idx == vif->shadow_ring->tx_idx ) BUG();
         tx  = &vif->shadow_ring->tx_ring[idx];
         vif->shadow_ring->tx_cons = TX_RING_INC(idx);
-        if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event )
-            set_bit(_EVENT_NET_TX, 
-                    &sys_vif_list[skb->src_vif]->domain->shared_info->events);
+        if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event ) send = 1;
     } while ( tx->status != RING_STATUS_OK );
 
     /* Now skip over any more bad descriptors, up to the next good one. */
@@ -705,13 +704,19 @@ static void tx_skb_release(struct sk_buff *skb)
              (tx->status == RING_STATUS_OK) )
             break;
         vif->shadow_ring->tx_cons = TX_RING_INC(idx);
-        if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event )
-            set_bit(_EVENT_NET_TX, 
-                    &sys_vif_list[skb->src_vif]->domain->shared_info->events);
+        if ( vif->shadow_ring->tx_cons == vif->net_ring->tx_event ) send = 1;
     } while ( 1 );
 
-    /* Finally, update shared consumer index to the new private value. */
+    /* Update shared consumer index to the new private value. */
     vif->net_ring->tx_cons = vif->shadow_ring->tx_cons;
+
+    /* Send a transmit event if requested. */
+    if ( send )
+    {
+        cpu_mask = mark_guest_event(
+            sys_vif_list[skb->src_vif]->domain, _EVENT_NET_TX);
+        guest_event_notify(cpu_mask);
+    }
 }
 
     
index adcff526b43f34848010077edd3457ab4d5d354a..7ef9ce4ef88e289432f2e690eb428443b2c1c93e 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <asm/io.h>
 #include <net/sock.h>
+#include <net/pkt_sched.h>
 
 #define NET_TX_IRQ _EVENT_NET_TX
 #define NET_RX_IRQ _EVENT_NET_RX
@@ -185,7 +186,8 @@ static void network_tx_buf_gc(struct net_device *dev)
         np->tx_idx = i;
         
         /* Set a new event, then check for race with update of tx_cons. */
-        np->net_ring->tx_event = TX_RING_INC(cons);
+        np->net_ring->tx_event =
+            TX_RING_ADD(cons, (atomic_read(&np->tx_entries)>>1) + 1);
         smp_mb();
     }
     while ( cons != np->net_ring->tx_cons );